﻿using AME.Setting;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using Serilog;
using System.Configuration;
using AME.Repository;

namespace AME.Database;

public static class RegisterSqlClient
{
    /// <summary>
    /// SqlClient注入Scoped
    /// </summary>
    /// <param name="services"></param>
    /// <returns></returns>
    public static IServiceCollection UseSqlSugar(this IServiceCollection services)
    {
        DbType dbType = (DbType)Enum.Parse(typeof(DbType), SettingExtensions.Configuration["DBConfig:DbType"] ?? throw new ConfigurationErrorsException("[DBConfig:DbType] error, please check appsettings.json"));
        string connectionString = SettingExtensions.Configuration["DBConfig:ConnectionStrings"] ?? throw new ConfigurationErrorsException("[DBConfig:ConnectionStrings] error, please check appsettings.json");

        services.AddScoped<ISqlSugarClient>(s =>
        {
            SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig()
            {
                DbType = dbType,
                ConnectionString = connectionString,
                IsAutoCloseConnection = true,
                InitKeyType = InitKeyType.Attribute // 从特性读取主键
            },
           db => //每次上下文都会执行
           {
               //SQL执行完
               db.Aop.OnLogExecuted = (sql, pars) =>
               {
                   //执行完了可以输出SQL执行时间 (OnLogExecutedDelegate) 
                   //Log.Information("time:" + db.Ado.SqlExecutionTime.ToString());
               };
               db.Aop.OnLogExecuting = (sql, pars) => //SQL执行前
               {
                   //获取原生SQL推荐 5.1.4.63  性能OK
                   //Log.Information($"Execution SQL : {UtilMethods.GetNativeSql(sql, pars)}");

               };
               db.Aop.OnError = (exp) =>//SQL报错
               {
                   //获取原生SQL推荐 5.1.4.63  性能OK
                   Log.Error($"SQL Execution Error : {exp.Message}");
                   Log.Error($"Execution SQL : {UtilMethods.GetNativeSql(exp.Sql,exp.Parametres as SugarParameter[])}");
                   //获取无参数SQL对性能有影响，特别大的SQL参数多的，调试使用
                   //UtilMethods.GetSqlString(DbType.SqlServer,exp.sql,exp.parameters)
               };
               db.Aop.OnExecutingChangeSql = (sql, pars) => //可以修改SQL和参数的值
               {
                   //sql=newsql
                   //foreach(var p in pars) //修改
                   return new KeyValuePair<string, SugarParameter[]>(sql, pars);
               };
               db.Aop.OnDiffLogEvent = it =>
               {
                   //操作前记录  包含： 字段描述 列名 值 表名 表描述
                   var editBeforeData = it.BeforeData;//插入Before为null，之前还没进库
                   //操作后记录   包含： 字段描述 列名 值  表名 表描述
                   var editAfterData = it.AfterData;
                   var sql = it.Sql;
                   var parameter = it.Parameters;
                   var data = it.BusinessData;//这边会显示你传进来的对象
                   var time = it.Time;
                   var diffType = it.DiffType;//enum insert 、update and delete

                   //Write logic
                   Log.Information($"Audit Log : ");
                   Log.Information($"Execute sql : {sql}");
                   Log.Information($"Execute time : {time}");
               };
           });
            return sqlSugar;
        });

        return services;
    }
}

